From 8f6ca4c787210df90e5e371a3cafe54400785252 Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" <15132211195@163.com> Date: Fri, 21 Jul 2023 03:09:56 +0000 Subject: Deploy mate-desktop/mate-netbook to github.com/mate-desktop/mate-netbook.git:gh-pages --- .../index.html | 140 ++ .../report-066e3e.html | 1009 +++++++++++++ .../report-07966d.html | 1009 +++++++++++++ .../report-167811.html | 901 ++++++++++++ .../report-1e2fd5.html | 1009 +++++++++++++ .../report-2eed80.html | 1009 +++++++++++++ .../report-519bf9.html | 1009 +++++++++++++ .../report-5555d9.html | 1009 +++++++++++++ .../report-87f973.html | 1009 +++++++++++++ .../report-8d22c7.html | 901 ++++++++++++ .../report-a2ef3d.html | 1009 +++++++++++++ .../report-b113da.html | 1009 +++++++++++++ .../report-bc0f47.html | 1009 +++++++++++++ .../report-cf4342.html | 849 +++++++++++ .../report-d86ec3.html | 1009 +++++++++++++ .../report-f8083f.html | 1009 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1489 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1273 ++++++++++++++++ .../3.html | 1169 +++++++++++++++ .../index.html | 129 ++ .../stats.html | 108 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-0af285.html | 901 ++++++++++++ .../report-12d4c1.html | 1009 +++++++++++++ .../report-35a7be.html | 1009 +++++++++++++ .../report-436dd6.html | 1009 +++++++++++++ .../report-44b187.html | 1009 +++++++++++++ .../report-6392ce.html | 1009 +++++++++++++ .../report-771039.html | 1009 +++++++++++++ .../report-8f2ecf.html | 1009 +++++++++++++ .../report-9fb331.html | 1009 +++++++++++++ .../report-a656a8.html | 1009 +++++++++++++ .../report-a9552c.html | 901 ++++++++++++ .../report-c24641.html | 1009 +++++++++++++ .../report-c9832e.html | 849 +++++++++++ .../report-d99c84.html | 1009 +++++++++++++ .../report-f5890d.html | 1009 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1489 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1273 ++++++++++++++++ .../3.html | 1169 +++++++++++++++ .../index.html | 129 ++ .../stats.html | 108 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-2e5333.html | 900 ++++++++++++ .../report-326845.html | 1008 +++++++++++++ .../report-336491.html | 1008 +++++++++++++ .../report-372a66.html | 1008 +++++++++++++ .../report-51b5f0.html | 900 ++++++++++++ .../report-522919.html | 1008 +++++++++++++ .../report-5c876e.html | 1008 +++++++++++++ .../report-85e0db.html | 846 +++++++++++ .../report-8d8a6a.html | 1008 +++++++++++++ .../report-a7affc.html | 1008 +++++++++++++ .../report-c01286.html | 1008 +++++++++++++ .../report-c17e44.html | 1008 +++++++++++++ .../report-cc16b0.html | 1008 +++++++++++++ .../report-e2a874.html | 1008 +++++++++++++ .../report-e488cf.html | 1008 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1487 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1271 ++++++++++++++++ .../3.html | 1163 +++++++++++++++ .../4.html | 853 +++++++++++ .../index.html | 132 ++ .../stats.html | 109 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-076df9.html | 1008 +++++++++++++ .../report-153039.html | 1008 +++++++++++++ .../report-26ef1a.html | 1008 +++++++++++++ .../report-295e70.html | 900 ++++++++++++ .../report-3500a3.html | 1008 +++++++++++++ .../report-39c9c4.html | 900 ++++++++++++ .../report-3fa9c9.html | 1008 +++++++++++++ .../report-532882.html | 1008 +++++++++++++ .../report-5fee6c.html | 1008 +++++++++++++ .../report-71d389.html | 1008 +++++++++++++ .../report-75a183.html | 846 +++++++++++ .../report-94cbc5.html | 1008 +++++++++++++ .../report-cba9e3.html | 1008 +++++++++++++ .../report-ecd83c.html | 1008 +++++++++++++ .../report-efae04.html | 1008 +++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1487 +++++++++++++++++++ .../1.html | 379 +++++ .../2.html | 1271 ++++++++++++++++ .../3.html | 1163 +++++++++++++++ .../4.html | 853 +++++++++++ .../index.html | 132 ++ .../stats.html | 109 ++ .../style.css | 137 ++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1174 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1225 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 216 +++ .../stats.html | 171 +++ .../style.css | 177 +++ .../index.html | 140 ++ .../report-05d832.html | 1336 +++++++++++++++++ .../report-1f618a.html | 1228 ++++++++++++++++ .../report-37b917.html | 1336 +++++++++++++++++ .../report-4bda9e.html | 1336 +++++++++++++++++ .../report-678a90.html | 1336 +++++++++++++++++ .../report-6fb882.html | 1336 +++++++++++++++++ .../report-7534c9.html | 1336 +++++++++++++++++ .../report-85a3e8.html | 1336 +++++++++++++++++ .../report-90bf5a.html | 1177 +++++++++++++++ .../report-aa2062.html | 1336 +++++++++++++++++ .../report-b10f27.html | 1336 +++++++++++++++++ .../report-c2cf20.html | 1336 +++++++++++++++++ .../report-e3bdb1.html | 1336 +++++++++++++++++ .../report-e9ff85.html | 1228 ++++++++++++++++ .../report-faab40.html | 1336 +++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++++ .../0.html | 1549 ++++++++++++++++++++ .../1.html | 441 ++++++ .../2.html | 1333 +++++++++++++++++ .../3.html | 1231 ++++++++++++++++ .../4.html | 915 ++++++++++++ .../index.html | 217 +++ .../stats.html | 171 +++ .../style.css | 177 +++ CNAME | 1 + index.html | 46 + 260 files changed, 240563 insertions(+) create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-066e3e.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-07966d.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-167811.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-1e2fd5.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-2eed80.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-519bf9.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-5555d9.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-87f973.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-8d22c7.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-a2ef3d.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-b113da.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-bc0f47.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-cf4342.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-d86ec3.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/report-f8083f.html create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/scanview.css create mode 100644 2021-06-21-213305-5323-1@e2f7cfd5fc80_master/sorttable.js create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/0.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/1.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/2.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/3.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/index.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/stats.html create mode 100644 2021-06-21-213330-4389-cppcheck@e2f7cfd5fc80_master/style.css create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/index.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-0af285.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-12d4c1.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-35a7be.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-436dd6.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-44b187.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-6392ce.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-771039.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-8f2ecf.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-9fb331.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a656a8.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-a9552c.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c24641.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-c9832e.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-d99c84.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/report-f5890d.html create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/scanview.css create mode 100644 2021-08-07-123620-5316-1@0778cc8da570_v1.26.0/sorttable.js create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/0.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/1.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/2.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/3.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/index.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/stats.html create mode 100644 2021-08-07-123646-6641-cppcheck@0778cc8da570_v1.26.0/style.css create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/index.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-2e5333.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-326845.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-336491.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-372a66.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-51b5f0.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-522919.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-5c876e.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-85e0db.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-8d8a6a.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-a7affc.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c01286.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-c17e44.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-cc16b0.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e2a874.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/report-e488cf.html create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/scanview.css create mode 100644 2021-12-11-150638-5462-1@d1ffecd40bf5_master/sorttable.js create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/0.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/1.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/2.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/3.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/4.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/index.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/stats.html create mode 100644 2021-12-11-150702-1198-cppcheck@d1ffecd40bf5_master/style.css create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/index.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-076df9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-153039.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-26ef1a.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-295e70.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3500a3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-39c9c4.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-3fa9c9.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-532882.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-5fee6c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-71d389.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-75a183.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-94cbc5.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-cba9e3.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-ecd83c.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/report-efae04.html create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/scanview.css create mode 100644 2022-02-13-183617-5516-1@becf3036fb90_master/sorttable.js create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/0.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/1.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/2.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/3.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/4.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/index.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/stats.html create mode 100644 2022-02-13-183640-2877-cppcheck@becf3036fb90_master/style.css create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/index.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-05d832.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-1f618a.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-37b917.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-4bda9e.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-678a90.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-6fb882.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-7534c9.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-85a3e8.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-90bf5a.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-aa2062.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-b10f27.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-c2cf20.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e3bdb1.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-e9ff85.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/report-faab40.html create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/scanview.css create mode 100644 2022-06-01-143057-5441-1@91cb104bb97b_configure_220601/sorttable.js create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/0.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/1.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/2.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/3.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/4.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/index.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/stats.html create mode 100644 2022-06-01-143121-4943-cppcheck@91cb104bb97b_configure_220601/style.css create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/index.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-05d832.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-1f618a.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-37b917.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-4bda9e.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-678a90.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-6fb882.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-7534c9.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-85a3e8.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-90bf5a.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-aa2062.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-b10f27.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-c2cf20.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-e3bdb1.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-e9ff85.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/report-faab40.html create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/scanview.css create mode 100644 2022-10-28-213107-5501-1@85b52143f8c1_master/sorttable.js create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/0.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/1.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/2.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/3.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/4.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/index.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/stats.html create mode 100644 2022-10-28-213131-8439-cppcheck@85b52143f8c1_master/style.css create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/index.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-05d832.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-1f618a.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-37b917.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-4bda9e.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-678a90.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-6fb882.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-7534c9.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-85a3e8.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-90bf5a.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-aa2062.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-b10f27.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-c2cf20.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-e3bdb1.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-e9ff85.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/report-faab40.html create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/scanview.css create mode 100644 2022-10-29-134752-5499-1@cd263b7986ec_master/sorttable.js create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/0.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/1.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/2.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/3.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/4.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/index.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/stats.html create mode 100644 2022-10-29-134815-0975-cppcheck@cd263b7986ec_master/style.css create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/index.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-05d832.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-1f618a.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-37b917.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-4bda9e.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-678a90.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-6fb882.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-7534c9.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-85a3e8.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-90bf5a.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-aa2062.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-b10f27.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-c2cf20.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e3bdb1.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-e9ff85.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/report-faab40.html create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/scanview.css create mode 100644 2022-11-11-180310-5358-1@6a7e6a9ee214_master/sorttable.js create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/0.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/1.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/2.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/3.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/4.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/index.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/stats.html create mode 100644 2022-11-11-180332-3296-cppcheck@6a7e6a9ee214_master/style.css create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/index.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-05d832.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-1f618a.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-37b917.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-4bda9e.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-678a90.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-6fb882.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-7534c9.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-85a3e8.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-90bf5a.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-aa2062.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-b10f27.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-c2cf20.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e3bdb1.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-e9ff85.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/report-faab40.html create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/scanview.css create mode 100644 2022-11-11-200407-5355-1@d39bd997538b_v1.27.0/sorttable.js create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/0.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/1.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/2.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/3.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/4.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/index.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/stats.html create mode 100644 2022-11-11-200430-4227-cppcheck@d39bd997538b_v1.27.0/style.css create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/index.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-05d832.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-1f618a.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-37b917.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-4bda9e.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-678a90.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-6fb882.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-7534c9.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-85a3e8.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-90bf5a.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-aa2062.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-b10f27.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-c2cf20.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e3bdb1.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-e9ff85.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/report-faab40.html create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/scanview.css create mode 100644 2023-07-21-030840-5334-1@6b49a8c0d49d_meson/sorttable.js create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/0.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/1.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/2.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/3.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/4.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/index.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/stats.html create mode 100644 2023-07-21-030903-7837-cppcheck@6b49a8c0d49d_meson/style.css create mode 100644 CNAME create mode 100644 index.html diff --git a/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html new file mode 100644 index 0000000..3832343 --- /dev/null +++ b/2021-06-21-213305-5323-1@e2f7cfd5fc80_master/index.html @@ -0,0 +1,140 @@ + +
+User: | root@0ed4f4d3ed32 |
---|---|
Working Directory: | /rootdir |
Command Line: | make -j 2 |
Clang Version: | clang version 12.0.0 (Fedora 12.0.0-2.fc34) + |
Date: | Mon Jun 21 21:33:05 2021 |
Bug Type | Quantity | Display? |
All Bugs | 15 | |
Dead store | ||
---|---|---|
Dead nested assignment | 1 | |
Logic error | ||
Cast from non-struct type to struct type | 2 | |
Security | ||
Potential insecure memory buffer bounds restriction in call 'strcpy' | 12 |
Bug Group | +Bug Type ▾ | +File | +Function/Method | +Line | +Path Length | ++ + |
Logic error | Cast from non-struct type to struct type | maximus-app.c | gdk_window_set_mwm_hints | 162 | 1 | View Report | + +
Logic error | Cast from non-struct type to struct type | maximus-app.c | wnck_window_is_decorated | 120 | 1 | View Report | + +
Dead store | Dead nested assignment | maximus-bind.c | maximus_bind_init | 467 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 429 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 454 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 439 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 404 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 409 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 458 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 449 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 414 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 419 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 424 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 444 | 1 | View Report | + +
Security | Potential insecure memory buffer bounds restriction in call 'strcpy' | eggaccelerators.c | egg_virtual_accelerator_name | 434 | 1 | View Report | + +
File: | eggaccelerators.c |
Warning: | line 429, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 454, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | maximus-app.c |
Warning: | line 162, column 13 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* |
2 | * Copyright (C) 2008 Canonical Ltd |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * |
5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 3 as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authored by Neil Jagdish Patel <neil.patel@canonical.com> |
18 | * |
19 | */ |
20 | |
21 | #include <stdio.h> |
22 | #include <string.h> |
23 | #include <unistd.h> |
24 | |
25 | #include <gtk/gtk.h> |
26 | #include <gdk/gdkx.h> |
27 | #include <gio/gio.h> |
28 | |
29 | #include "maximus-app.h" |
30 | #include "maximus-bind.h" |
31 | #include "xutils.h" |
32 | |
33 | /* GSettings schemas and keys */ |
34 | #define APP_SCHEMA"org.mate.maximus" "org.mate.maximus" |
35 | #define APP_EXCLUDE_CLASS"exclude-class" "exclude-class" |
36 | #define APP_UNDECORATE"undecorate" "undecorate" |
37 | #define APP_NO_MAXIMIZE"no-maximize" "no-maximize" |
38 | |
39 | /* A set of default exceptions */ |
40 | static gchar *default_exclude_classes[] = |
41 | { |
42 | "Apport-gtk", |
43 | "Bluetooth-properties", |
44 | "Bluetooth-wizard", |
45 | "Download", /* Firefox Download Window */ |
46 | "Ekiga", |
47 | "Extension", /* Firefox Add-Ons/Extension Window */ |
48 | "Gcalctool", |
49 | "Gimp", |
50 | "Global", /* Firefox Error Console Window */ |
51 | "Mate-dictionary", |
52 | "Mate-language-selector", |
53 | "Mate-nettool", |
54 | "Mate-volume-control", |
55 | "Kiten", |
56 | "Kmplot", |
57 | "Nm-editor", |
58 | "Pidgin", |
59 | "Polkit-mate-authorization", |
60 | "Update-manager", |
61 | "Skype", |
62 | "Toplevel", /* Firefox "Clear Private Data" Window */ |
63 | "Transmission" |
64 | }; |
65 | |
66 | struct _MaximusAppPrivate |
67 | { |
68 | MaximusBind *bind; |
69 | WnckScreen *screen; |
70 | GSettings *settings; |
71 | |
72 | gchar **exclude_class_list; |
73 | gboolean undecorate; |
74 | gboolean no_maximize; |
75 | }; |
76 | |
77 | static GQuark was_decorated = 0; |
78 | |
79 | /* <TAKEN FROM GDK> */ |
80 | typedef struct { |
81 | unsigned long flags; |
82 | unsigned long functions; |
83 | unsigned long decorations; |
84 | long input_mode; |
85 | unsigned long status; |
86 | } MotifWmHints, MwmHints; |
87 | |
88 | #define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0) |
89 | #define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1) |
90 | #define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS" |
91 | |
92 | G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init (MaximusAppClass *klass); static GType maximus_app_get_type_once (void); static gpointer maximus_app_parent_class = ((void*)0 ); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init (gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent (klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset (klass, &MaximusApp_private_offset); maximus_app_class_init ((MaximusAppClass*) klass); } __attribute__((__unused__)) static inline gpointer maximus_app_get_instance_private (MaximusApp *self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset )))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0 )); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = maximus_app_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__((noinline)) static GType maximus_app_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("MaximusApp" ), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void)) maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc )(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate )); };} } return g_define_type_id; }; |
93 | |
94 | static gboolean |
95 | wnck_window_is_decorated (WnckWindow *window) |
96 | { |
97 | GdkDisplay *display = gdk_display_get_default(); |
98 | Atom hints_atom = None0L; |
99 | guchar *data = NULL((void*)0); |
100 | MotifWmHints *hints = NULL((void*)0); |
101 | Atom type = None0L; |
102 | gint format; |
103 | gulong nitems; |
104 | gulong bytes_after; |
105 | gboolean retval; |
106 | |
107 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
108 | |
109 | hints_atom = gdk_x11_get_xatom_by_name_for_display (display, |
110 | _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS"); |
111 | |
112 | XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
113 | wnck_window_get_xid (window), |
114 | hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), |
115 | False0, AnyPropertyType0L, &type, &format, &nitems, |
116 | &bytes_after, &data); |
117 | |
118 | if (type == None0L || !data) return TRUE(!(0)); |
119 | |
120 | hints = (MotifWmHints *)data; |
121 | |
122 | retval = hints->decorations; |
123 | |
124 | if (data) |
125 | XFree (data); |
126 | |
127 | return retval; |
128 | } |
129 | |
130 | static void |
131 | gdk_window_set_mwm_hints (WnckWindow *window, |
132 | MotifWmHints *new_hints) |
133 | { |
134 | GdkDisplay *display = gdk_display_get_default(); |
135 | Atom hints_atom = None0L; |
136 | guchar *data = NULL((void*)0); |
137 | MotifWmHints *hints = NULL((void*)0); |
138 | Atom type = None0L; |
139 | gint format; |
140 | gulong nitems; |
141 | gulong bytes_after; |
142 | |
143 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
144 | g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((gdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while (0); |
145 | |
146 | hints_atom = gdk_x11_get_xatom_by_name_for_display (display, |
147 | _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS"); |
148 | |
149 | gdk_x11_display_error_trap_push (display); |
150 | XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
151 | wnck_window_get_xid (window), |
152 | hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), |
153 | False0, AnyPropertyType0L, &type, &format, &nitems, |
154 | &bytes_after, &data); |
155 | if (gdk_x11_display_error_trap_pop (display)) |
156 | return; |
157 | |
158 | if (type != hints_atom || !data) |
159 | hints = new_hints; |
160 | else |
161 | { |
162 | hints = (MotifWmHints *)data; |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
163 | |
164 | if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0)) |
165 | { |
166 | hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0); |
167 | hints->functions = new_hints->functions; |
168 | } |
169 | if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1)) |
170 | { |
171 | hints->flags |= MWM_HINTS_DECORATIONS(1L << 1); |
172 | hints->decorations = new_hints->decorations; |
173 | } |
174 | } |
175 | |
176 | _wnck_error_trap_push (); |
177 | XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
178 | wnck_window_get_xid (window), |
179 | hints_atom, hints_atom, 32, PropModeReplace0, |
180 | (guchar *)hints, sizeof (MotifWmHints)/sizeof (long)); |
181 | gdk_display_flush (display); |
182 | _wnck_error_trap_pop (); |
183 | |
184 | if (data) |
185 | XFree (data); |
186 | } |
187 | |
188 | static void |
189 | _window_set_decorations (WnckWindow *window, |
190 | GdkWMDecoration decorations) |
191 | { |
192 | MotifWmHints *hints; |
193 | |
194 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
195 | |
196 | /* initialize to zero to avoid writing uninitialized data to socket */ |
197 | hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints ); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s ); __p; })); |
198 | hints->flags = MWM_HINTS_DECORATIONS(1L << 1); |
199 | hints->decorations = decorations; |
200 | |
201 | gdk_window_set_mwm_hints (window, hints); |
202 | |
203 | g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else (void) ((MotifWmHints*) 0 == (hints)); } while (0); |
204 | } |
205 | |
206 | /* </TAKEN FROM GDK> */ |
207 | |
208 | gboolean |
209 | window_is_too_large_for_screen (WnckWindow *window) |
210 | { |
211 | static GdkScreen *screen = NULL((void*)0); |
212 | gint x=0, y=0, w=0, h=0; |
213 | |
214 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
215 | |
216 | if (screen == NULL((void*)0)) |
217 | screen = gdk_screen_get_default (); |
218 | |
219 | wnck_window_get_geometry (window, &x, &y, &w, &h); |
220 | |
221 | /* some wiggle room */ |
222 | return (screen && |
223 | (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) || |
224 | h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20))); |
225 | } |
226 | |
227 | static gboolean |
228 | on_window_maximised_changed (WnckWindow *window) |
229 | { |
230 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
231 | |
232 | if (window_is_too_large_for_screen (window)) |
233 | { |
234 | _window_set_decorations (window, 1); |
235 | wnck_window_unmaximize (window); |
236 | } |
237 | else |
238 | { |
239 | _window_set_decorations (window, 0); |
240 | } |
241 | return FALSE(0); |
242 | } |
243 | |
244 | static gboolean |
245 | enable_window_decorations (WnckWindow *window) |
246 | { |
247 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
248 | |
249 | _window_set_decorations (window, 1); |
250 | return FALSE(0); |
251 | } |
252 | |
253 | static void |
254 | on_window_state_changed (WnckWindow *window, |
255 | WnckWindowState change_mask, |
256 | WnckWindowState new_state, |
257 | MaximusApp *app) |
258 | { |
259 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
260 | |
261 | if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((window)), (((GType) ((20) << (2))) ))))), "exclude")))==1) |
262 | return; |
263 | |
264 | if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
265 | || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY) |
266 | { |
267 | if (wnck_window_is_maximized (window) && app->priv->undecorate) |
268 | { |
269 | g_idle_add ((GSourceFunc)on_window_maximised_changed, window); |
270 | } |
271 | else |
272 | { |
273 | g_idle_add ((GSourceFunc)enable_window_decorations, window); |
274 | } |
275 | } |
276 | } |
277 | |
278 | static gboolean |
279 | is_excluded (MaximusApp *app, WnckWindow *window) |
280 | { |
281 | MaximusAppPrivate *priv; |
282 | WnckWindowType type; |
283 | WnckWindowActions actions; |
284 | gchar *res_name; |
285 | gchar *class_name; |
286 | gint i; |
287 | |
288 | g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while (0); |
289 | g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); } } while (0); |
290 | priv = app->priv; |
291 | |
292 | type = wnck_window_get_window_type (window); |
293 | if (type != WNCK_WINDOW_NORMAL) |
294 | return TRUE(!(0)); |
295 | |
296 | if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((window)), (((GType) ((20) << (2))) ))))), "exclude")))==1) |
297 | return TRUE(!(0)); |
298 | |
299 | /* Ignore if the window is already fullscreen */ |
300 | if (wnck_window_is_fullscreen (window)) |
301 | { |
302 | g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window)); |
303 | return TRUE(!(0)); |
304 | } |
305 | |
306 | /* Make sure the window supports maximising */ |
307 | actions = wnck_window_get_actions (window); |
308 | if (actions & WNCK_WINDOW_ACTION_RESIZE |
309 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY |
310 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY |
311 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE) |
312 | ; /* Is good to maximise */ |
313 | else |
314 | return TRUE(!(0)); |
315 | |
316 | _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name); |
317 | |
318 | g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name); |
319 | |
320 | /* Check internal list of class_ids */ |
321 | for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes )[0])); i++) |
322 | { |
323 | if ((class_name && default_exclude_classes[i] |
324 | && strstr (class_name, default_exclude_classes[i])) |
325 | || (res_name && default_exclude_classes[i] && strstr (res_name, |
326 | default_exclude_classes[i]))) |
327 | { |
328 | g_debug ("Excluding: %s\n", wnck_window_get_name (window)); |
329 | return TRUE(!(0)); |
330 | } |
331 | } |
332 | |
333 | /* Check user list */ |
334 | for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++) |
335 | { |
336 | if ((class_name && strstr (class_name, priv->exclude_class_list[i])) |
337 | || (res_name && strstr (res_name, priv->exclude_class_list[i]) )) |
338 | { |
339 | g_debug ("Excluding: %s\n", wnck_window_get_name (window)); |
340 | return TRUE(!(0)); |
341 | } |
342 | } |
343 | |
344 | g_free (res_name); |
345 | g_free (class_name); |
346 | return FALSE(0); |
347 | } |
348 | |
349 | extern gboolean no_maximize; |
350 | |
351 | static void |
352 | on_window_opened (WnckScreen *screen, |
353 | WnckWindow *window, |
354 | MaximusApp *app) |
355 | { |
356 | MaximusAppPrivate *priv; |
357 | WnckWindowType type; |
358 | gint exclude = 0; |
359 | GdkDisplay *gdk_display = gdk_display_get_default (); |
360 | |
361 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
362 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
363 | priv = app->priv; |
364 | |
365 | type = wnck_window_get_window_type (window); |
366 | if (type != WNCK_WINDOW_NORMAL) |
367 | return; |
368 | |
369 | /* Ignore undecorated windows */ |
370 | gdk_x11_display_error_trap_push (gdk_display); |
371 | exclude = wnck_window_is_decorated (window) ? 0 : 1; |
372 | if (gdk_x11_display_error_trap_pop (gdk_display)) |
373 | return; |
374 | |
375 | if (wnck_window_is_maximized (window)) |
376 | exclude = 0; |
377 | g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( window)), (((GType) ((20) << (2)))))))), "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude))); |
378 | |
379 | if (is_excluded (app, window)) |
380 | { |
381 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
382 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
383 | return; |
384 | } |
385 | |
386 | if (no_maximize || priv->no_maximize) |
387 | { |
388 | if (wnck_window_is_maximized(window) && priv->undecorate) |
389 | { |
390 | _window_set_decorations (window, 0); |
391 | gdk_display_flush (gdk_display); |
392 | } |
393 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
394 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
395 | return; |
396 | } |
397 | |
398 | if (priv->undecorate) |
399 | { |
400 | /* Only undecorate right now if the window is smaller than the screen */ |
401 | if (!window_is_too_large_for_screen (window)) |
402 | { |
403 | _window_set_decorations (window, 0); |
404 | gdk_display_flush (gdk_display); |
405 | } |
406 | } |
407 | |
408 | wnck_window_maximize (window); |
409 | |
410 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
411 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
412 | } |
413 | |
414 | /* GSettings Callbacks */ |
415 | static void |
416 | on_app_no_maximize_changed (GSettings *settings, |
417 | gchar *key, |
418 | MaximusApp *app) |
419 | { |
420 | MaximusAppPrivate *priv; |
421 | |
422 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
423 | priv = app->priv; |
424 | priv->no_maximize = g_settings_get_boolean (settings, key); |
425 | } |
426 | |
427 | static void |
428 | on_exclude_class_changed (GSettings *settings, |
429 | gchar *key, |
430 | MaximusApp *app) |
431 | { |
432 | MaximusAppPrivate *priv; |
433 | |
434 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
435 | priv = app->priv; |
436 | |
437 | if (priv->exclude_class_list) |
438 | g_strfreev (priv->exclude_class_list); |
439 | |
440 | priv->exclude_class_list= g_settings_get_strv (settings, |
441 | APP_EXCLUDE_CLASS"exclude-class"); |
442 | } |
443 | |
444 | static gboolean |
445 | show_desktop (WnckScreen *screen) |
446 | { |
447 | g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while (0); |
448 | |
449 | wnck_screen_toggle_showing_desktop (screen, TRUE(!(0))); |
450 | return FALSE(0); |
451 | } |
452 | |
453 | static void |
454 | on_app_undecorate_changed (GSettings *settings, |
455 | gchar *key, |
456 | MaximusApp *app) |
457 | { |
458 | MaximusAppPrivate *priv; |
459 | GList *windows, *w; |
460 | |
461 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
462 | priv = app->priv; |
463 | g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((priv->screen)); GType __t = ((wnck_screen_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_ ; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)" ); return; } } while (0); |
464 | |
465 | priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate"); |
466 | g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating"); |
467 | |
468 | windows = wnck_screen_get_windows (priv->screen); |
469 | for (w = windows; w; w = w->next) |
470 | { |
471 | WnckWindow *window = w->data; |
472 | |
473 | if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (window)); GType __t = ((wnck_window_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
474 | continue; |
475 | |
476 | if (no_maximize || priv->no_maximize) |
477 | { |
478 | if (!wnck_window_is_maximized(window)) |
479 | continue; |
480 | } |
481 | |
482 | if (!is_excluded (app, window)) |
483 | { |
484 | GdkDisplay *gdk_display = gdk_display_get_default (); |
485 | |
486 | gdk_x11_display_error_trap_push (gdk_display); |
487 | _window_set_decorations (window, priv->undecorate ? 0 : 1); |
488 | wnck_window_unmaximize (window); |
489 | wnck_window_maximize (window); |
490 | gdk_display_flush (gdk_display); |
491 | gdk_x11_display_error_trap_pop_ignored (gdk_display); |
492 | |
493 | sleep (1); |
494 | } |
495 | } |
496 | /* We want the user to be left on the launcher/desktop after switching modes*/ |
497 | g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen); |
498 | } |
499 | |
500 | |
501 | /* GObject stuff */ |
502 | static void |
503 | maximus_app_class_init (MaximusAppClass *klass) |
504 | { |
505 | } |
506 | |
507 | static void |
508 | maximus_app_init (MaximusApp *app) |
509 | { |
510 | MaximusAppPrivate *priv; |
511 | WnckScreen *screen; |
512 | |
513 | priv = app->priv = maximus_app_get_instance_private (app); |
514 | |
515 | priv->bind = maximus_bind_get_default (); |
516 | |
517 | was_decorated = g_quark_from_static_string ("was-decorated"); |
518 | |
519 | priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus"); |
520 | |
521 | g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class" ), (((GCallback) (on_exclude_class_changed))), (app), ((void* )0), (GConnectFlags) 0) |
522 | G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class" ), (((GCallback) (on_exclude_class_changed))), (app), ((void* )0), (GConnectFlags) 0); |
523 | g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate" ), (((GCallback) (on_app_undecorate_changed))), (app), ((void *)0), (GConnectFlags) 0) |
524 | G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate" ), (((GCallback) (on_app_undecorate_changed))), (app), ((void *)0), (GConnectFlags) 0); |
525 | g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize" ), (((GCallback) (on_app_no_maximize_changed))), (app), ((void *)0), (GConnectFlags) 0) |
526 | G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize" ), (((GCallback) (on_app_no_maximize_changed))), (app), ((void *)0), (GConnectFlags) 0); |
527 | |
528 | priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class"); |
529 | priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate"); |
530 | priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize"); |
531 | g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false"); |
532 | |
533 | priv->screen = screen = wnck_screen_get_default (); |
534 | g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback ) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0) |
535 | G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback ) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0); |
536 | } |
537 | |
538 | MaximusApp * |
539 | maximus_app_get_default (void) |
540 | |
541 | { |
542 | static MaximusApp *app = NULL((void*)0); |
543 | |
544 | if (!app) |
545 | app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()), |
546 | NULL((void*)0)); |
547 | |
548 | return app; |
549 | } |
File: | eggaccelerators.c |
Warning: | line 439, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 404, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 409, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 458, column 3 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 449, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | maximus-app.c |
Warning: | line 120, column 11 Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* |
2 | * Copyright (C) 2008 Canonical Ltd |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * |
5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 3 as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authored by Neil Jagdish Patel <neil.patel@canonical.com> |
18 | * |
19 | */ |
20 | |
21 | #include <stdio.h> |
22 | #include <string.h> |
23 | #include <unistd.h> |
24 | |
25 | #include <gtk/gtk.h> |
26 | #include <gdk/gdkx.h> |
27 | #include <gio/gio.h> |
28 | |
29 | #include "maximus-app.h" |
30 | #include "maximus-bind.h" |
31 | #include "xutils.h" |
32 | |
33 | /* GSettings schemas and keys */ |
34 | #define APP_SCHEMA"org.mate.maximus" "org.mate.maximus" |
35 | #define APP_EXCLUDE_CLASS"exclude-class" "exclude-class" |
36 | #define APP_UNDECORATE"undecorate" "undecorate" |
37 | #define APP_NO_MAXIMIZE"no-maximize" "no-maximize" |
38 | |
39 | /* A set of default exceptions */ |
40 | static gchar *default_exclude_classes[] = |
41 | { |
42 | "Apport-gtk", |
43 | "Bluetooth-properties", |
44 | "Bluetooth-wizard", |
45 | "Download", /* Firefox Download Window */ |
46 | "Ekiga", |
47 | "Extension", /* Firefox Add-Ons/Extension Window */ |
48 | "Gcalctool", |
49 | "Gimp", |
50 | "Global", /* Firefox Error Console Window */ |
51 | "Mate-dictionary", |
52 | "Mate-language-selector", |
53 | "Mate-nettool", |
54 | "Mate-volume-control", |
55 | "Kiten", |
56 | "Kmplot", |
57 | "Nm-editor", |
58 | "Pidgin", |
59 | "Polkit-mate-authorization", |
60 | "Update-manager", |
61 | "Skype", |
62 | "Toplevel", /* Firefox "Clear Private Data" Window */ |
63 | "Transmission" |
64 | }; |
65 | |
66 | struct _MaximusAppPrivate |
67 | { |
68 | MaximusBind *bind; |
69 | WnckScreen *screen; |
70 | GSettings *settings; |
71 | |
72 | gchar **exclude_class_list; |
73 | gboolean undecorate; |
74 | gboolean no_maximize; |
75 | }; |
76 | |
77 | static GQuark was_decorated = 0; |
78 | |
79 | /* <TAKEN FROM GDK> */ |
80 | typedef struct { |
81 | unsigned long flags; |
82 | unsigned long functions; |
83 | unsigned long decorations; |
84 | long input_mode; |
85 | unsigned long status; |
86 | } MotifWmHints, MwmHints; |
87 | |
88 | #define MWM_HINTS_FUNCTIONS(1L << 0) (1L << 0) |
89 | #define MWM_HINTS_DECORATIONS(1L << 1) (1L << 1) |
90 | #define _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS" "_MOTIF_WM_HINTS" |
91 | |
92 | G_DEFINE_TYPE_WITH_PRIVATE (MaximusApp, maximus_app, G_TYPE_OBJECT)static void maximus_app_init (MaximusApp *self); static void maximus_app_class_init (MaximusAppClass *klass); static GType maximus_app_get_type_once (void); static gpointer maximus_app_parent_class = ((void*)0 ); static gint MaximusApp_private_offset; static void maximus_app_class_intern_init (gpointer klass) { maximus_app_parent_class = g_type_class_peek_parent (klass); if (MaximusApp_private_offset != 0) g_type_class_adjust_private_offset (klass, &MaximusApp_private_offset); maximus_app_class_init ((MaximusAppClass*) klass); } __attribute__((__unused__)) static inline gpointer maximus_app_get_instance_private (MaximusApp *self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusApp_private_offset )))); } GType maximus_app_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0 )); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = maximus_app_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__((noinline)) static GType maximus_app_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("MaximusApp" ), sizeof (MaximusAppClass), (GClassInitFunc)(void (*)(void)) maximus_app_class_intern_init, sizeof (MaximusApp), (GInstanceInitFunc )(void (*)(void)) maximus_app_init, (GTypeFlags) 0); { {{ MaximusApp_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (MaximusAppPrivate )); };} } return g_define_type_id; }; |
93 | |
94 | static gboolean |
95 | wnck_window_is_decorated (WnckWindow *window) |
96 | { |
97 | GdkDisplay *display = gdk_display_get_default(); |
98 | Atom hints_atom = None0L; |
99 | guchar *data = NULL((void*)0); |
100 | MotifWmHints *hints = NULL((void*)0); |
101 | Atom type = None0L; |
102 | gint format; |
103 | gulong nitems; |
104 | gulong bytes_after; |
105 | gboolean retval; |
106 | |
107 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
108 | |
109 | hints_atom = gdk_x11_get_xatom_by_name_for_display (display, |
110 | _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS"); |
111 | |
112 | XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
113 | wnck_window_get_xid (window), |
114 | hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), |
115 | False0, AnyPropertyType0L, &type, &format, &nitems, |
116 | &bytes_after, &data); |
117 | |
118 | if (type == None0L || !data) return TRUE(!(0)); |
119 | |
120 | hints = (MotifWmHints *)data; |
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption | |
121 | |
122 | retval = hints->decorations; |
123 | |
124 | if (data) |
125 | XFree (data); |
126 | |
127 | return retval; |
128 | } |
129 | |
130 | static void |
131 | gdk_window_set_mwm_hints (WnckWindow *window, |
132 | MotifWmHints *new_hints) |
133 | { |
134 | GdkDisplay *display = gdk_display_get_default(); |
135 | Atom hints_atom = None0L; |
136 | guchar *data = NULL((void*)0); |
137 | MotifWmHints *hints = NULL((void*)0); |
138 | Atom type = None0L; |
139 | gint format; |
140 | gulong nitems; |
141 | gulong bytes_after; |
142 | |
143 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
144 | g_return_if_fail (GDK_IS_DISPLAY (display))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((gdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_DISPLAY (display)"); return; } } while (0); |
145 | |
146 | hints_atom = gdk_x11_get_xatom_by_name_for_display (display, |
147 | _XA_MOTIF_WM_HINTS"_MOTIF_WM_HINTS"); |
148 | |
149 | gdk_x11_display_error_trap_push (display); |
150 | XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
151 | wnck_window_get_xid (window), |
152 | hints_atom, 0, sizeof (MotifWmHints)/sizeof (long), |
153 | False0, AnyPropertyType0L, &type, &format, &nitems, |
154 | &bytes_after, &data); |
155 | if (gdk_x11_display_error_trap_pop (display)) |
156 | return; |
157 | |
158 | if (type != hints_atom || !data) |
159 | hints = new_hints; |
160 | else |
161 | { |
162 | hints = (MotifWmHints *)data; |
163 | |
164 | if (new_hints->flags & MWM_HINTS_FUNCTIONS(1L << 0)) |
165 | { |
166 | hints->flags |= MWM_HINTS_FUNCTIONS(1L << 0); |
167 | hints->functions = new_hints->functions; |
168 | } |
169 | if (new_hints->flags & MWM_HINTS_DECORATIONS(1L << 1)) |
170 | { |
171 | hints->flags |= MWM_HINTS_DECORATIONS(1L << 1); |
172 | hints->decorations = new_hints->decorations; |
173 | } |
174 | } |
175 | |
176 | _wnck_error_trap_push (); |
177 | XChangeProperty (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display)), |
178 | wnck_window_get_xid (window), |
179 | hints_atom, hints_atom, 32, PropModeReplace0, |
180 | (guchar *)hints, sizeof (MotifWmHints)/sizeof (long)); |
181 | gdk_display_flush (display); |
182 | _wnck_error_trap_pop (); |
183 | |
184 | if (data) |
185 | XFree (data); |
186 | } |
187 | |
188 | static void |
189 | _window_set_decorations (WnckWindow *window, |
190 | GdkWMDecoration decorations) |
191 | { |
192 | MotifWmHints *hints; |
193 | |
194 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
195 | |
196 | /* initialize to zero to avoid writing uninitialized data to socket */ |
197 | hints = g_slice_new0 (MotifWmHints)(MotifWmHints *) (__extension__ ({ gsize __s = sizeof (MotifWmHints ); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s ); __p; })); |
198 | hints->flags = MWM_HINTS_DECORATIONS(1L << 1); |
199 | hints->decorations = decorations; |
200 | |
201 | gdk_window_set_mwm_hints (window, hints); |
202 | |
203 | g_slice_free (MotifWmHints, hints)do { if (1) g_slice_free1 (sizeof (MotifWmHints), (hints)); else (void) ((MotifWmHints*) 0 == (hints)); } while (0); |
204 | } |
205 | |
206 | /* </TAKEN FROM GDK> */ |
207 | |
208 | gboolean |
209 | window_is_too_large_for_screen (WnckWindow *window) |
210 | { |
211 | static GdkScreen *screen = NULL((void*)0); |
212 | gint x=0, y=0, w=0, h=0; |
213 | |
214 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
215 | |
216 | if (screen == NULL((void*)0)) |
217 | screen = gdk_screen_get_default (); |
218 | |
219 | wnck_window_get_geometry (window, &x, &y, &w, &h); |
220 | |
221 | /* some wiggle room */ |
222 | return (screen && |
223 | (w > (WidthOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->width) + 20) || |
224 | h > (HeightOfScreen (gdk_x11_screen_get_xscreen (screen))((gdk_x11_screen_get_xscreen (screen))->height) + 20))); |
225 | } |
226 | |
227 | static gboolean |
228 | on_window_maximised_changed (WnckWindow *window) |
229 | { |
230 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
231 | |
232 | if (window_is_too_large_for_screen (window)) |
233 | { |
234 | _window_set_decorations (window, 1); |
235 | wnck_window_unmaximize (window); |
236 | } |
237 | else |
238 | { |
239 | _window_set_decorations (window, 0); |
240 | } |
241 | return FALSE(0); |
242 | } |
243 | |
244 | static gboolean |
245 | enable_window_decorations (WnckWindow *window) |
246 | { |
247 | g_return_val_if_fail (WNCK_IS_WINDOW (window), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((0)); } } while (0); |
248 | |
249 | _window_set_decorations (window, 1); |
250 | return FALSE(0); |
251 | } |
252 | |
253 | static void |
254 | on_window_state_changed (WnckWindow *window, |
255 | WnckWindowState change_mask, |
256 | WnckWindowState new_state, |
257 | MaximusApp *app) |
258 | { |
259 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
260 | |
261 | if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((window)), (((GType) ((20) << (2))) ))))), "exclude")))==1) |
262 | return; |
263 | |
264 | if (change_mask & WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY |
265 | || change_mask & WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY) |
266 | { |
267 | if (wnck_window_is_maximized (window) && app->priv->undecorate) |
268 | { |
269 | g_idle_add ((GSourceFunc)on_window_maximised_changed, window); |
270 | } |
271 | else |
272 | { |
273 | g_idle_add ((GSourceFunc)enable_window_decorations, window); |
274 | } |
275 | } |
276 | } |
277 | |
278 | static gboolean |
279 | is_excluded (MaximusApp *app, WnckWindow *window) |
280 | { |
281 | MaximusAppPrivate *priv; |
282 | WnckWindowType type; |
283 | WnckWindowActions actions; |
284 | gchar *res_name; |
285 | gchar *class_name; |
286 | gint i; |
287 | |
288 | g_return_val_if_fail (MAXIMUS_IS_APP (app), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return ((!(0))); } } while (0); |
289 | g_return_val_if_fail (WNCK_IS_WINDOW (window), TRUE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return ((!(0))); } } while (0); |
290 | priv = app->priv; |
291 | |
292 | type = wnck_window_get_window_type (window); |
293 | if (type != WNCK_WINDOW_NORMAL) |
294 | return TRUE(!(0)); |
295 | |
296 | if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "exclude"))((gint) (glong) (g_object_get_data (((((GObject*) g_type_check_instance_cast ((GTypeInstance*) ((window)), (((GType) ((20) << (2))) ))))), "exclude")))==1) |
297 | return TRUE(!(0)); |
298 | |
299 | /* Ignore if the window is already fullscreen */ |
300 | if (wnck_window_is_fullscreen (window)) |
301 | { |
302 | g_debug ("Excluding (is fullscreen): %s\n",wnck_window_get_name (window)); |
303 | return TRUE(!(0)); |
304 | } |
305 | |
306 | /* Make sure the window supports maximising */ |
307 | actions = wnck_window_get_actions (window); |
308 | if (actions & WNCK_WINDOW_ACTION_RESIZE |
309 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE_HORIZONTALLY |
310 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE_VERTICALLY |
311 | && actions & WNCK_WINDOW_ACTION_MAXIMIZE) |
312 | ; /* Is good to maximise */ |
313 | else |
314 | return TRUE(!(0)); |
315 | |
316 | _wnck_get_wmclass (wnck_window_get_xid (window), &res_name, &class_name); |
317 | |
318 | g_debug ("Window opened: res_name=%s -- class_name=%s", res_name, class_name); |
319 | |
320 | /* Check internal list of class_ids */ |
321 | for (i = 0; i < G_N_ELEMENTS (default_exclude_classes)(sizeof (default_exclude_classes) / sizeof ((default_exclude_classes )[0])); i++) |
322 | { |
323 | if ((class_name && default_exclude_classes[i] |
324 | && strstr (class_name, default_exclude_classes[i])) |
325 | || (res_name && default_exclude_classes[i] && strstr (res_name, |
326 | default_exclude_classes[i]))) |
327 | { |
328 | g_debug ("Excluding: %s\n", wnck_window_get_name (window)); |
329 | return TRUE(!(0)); |
330 | } |
331 | } |
332 | |
333 | /* Check user list */ |
334 | for (i = 0; priv->exclude_class_list[i] != NULL((void*)0); i++) |
335 | { |
336 | if ((class_name && strstr (class_name, priv->exclude_class_list[i])) |
337 | || (res_name && strstr (res_name, priv->exclude_class_list[i]) )) |
338 | { |
339 | g_debug ("Excluding: %s\n", wnck_window_get_name (window)); |
340 | return TRUE(!(0)); |
341 | } |
342 | } |
343 | |
344 | g_free (res_name); |
345 | g_free (class_name); |
346 | return FALSE(0); |
347 | } |
348 | |
349 | extern gboolean no_maximize; |
350 | |
351 | static void |
352 | on_window_opened (WnckScreen *screen, |
353 | WnckWindow *window, |
354 | MaximusApp *app) |
355 | { |
356 | MaximusAppPrivate *priv; |
357 | WnckWindowType type; |
358 | gint exclude = 0; |
359 | GdkDisplay *gdk_display = gdk_display_get_default (); |
360 | |
361 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
362 | g_return_if_fail (WNCK_IS_WINDOW (window))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((window)); GType __t = ((wnck_window_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_WINDOW (window)"); return; } } while ( 0); |
363 | priv = app->priv; |
364 | |
365 | type = wnck_window_get_window_type (window); |
366 | if (type != WNCK_WINDOW_NORMAL) |
367 | return; |
368 | |
369 | /* Ignore undecorated windows */ |
370 | gdk_x11_display_error_trap_push (gdk_display); |
371 | exclude = wnck_window_is_decorated (window) ? 0 : 1; |
372 | if (gdk_x11_display_error_trap_pop (gdk_display)) |
373 | return; |
374 | |
375 | if (wnck_window_is_maximized (window)) |
376 | exclude = 0; |
377 | g_object_set_data (G_OBJECT (window)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( window)), (((GType) ((20) << (2)))))))), "exclude", GINT_TO_POINTER (exclude)((gpointer) (glong) (exclude))); |
378 | |
379 | if (is_excluded (app, window)) |
380 | { |
381 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
382 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
383 | return; |
384 | } |
385 | |
386 | if (no_maximize || priv->no_maximize) |
387 | { |
388 | if (wnck_window_is_maximized(window) && priv->undecorate) |
389 | { |
390 | _window_set_decorations (window, 0); |
391 | gdk_display_flush (gdk_display); |
392 | } |
393 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
394 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
395 | return; |
396 | } |
397 | |
398 | if (priv->undecorate) |
399 | { |
400 | /* Only undecorate right now if the window is smaller than the screen */ |
401 | if (!window_is_too_large_for_screen (window)) |
402 | { |
403 | _window_set_decorations (window, 0); |
404 | gdk_display_flush (gdk_display); |
405 | } |
406 | } |
407 | |
408 | wnck_window_maximize (window); |
409 | |
410 | g_signal_connect (window, "state-changed",g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0) |
411 | G_CALLBACK (on_window_state_changed), app)g_signal_connect_data ((window), ("state-changed"), (((GCallback ) (on_window_state_changed))), (app), ((void*)0), (GConnectFlags ) 0); |
412 | } |
413 | |
414 | /* GSettings Callbacks */ |
415 | static void |
416 | on_app_no_maximize_changed (GSettings *settings, |
417 | gchar *key, |
418 | MaximusApp *app) |
419 | { |
420 | MaximusAppPrivate *priv; |
421 | |
422 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
423 | priv = app->priv; |
424 | priv->no_maximize = g_settings_get_boolean (settings, key); |
425 | } |
426 | |
427 | static void |
428 | on_exclude_class_changed (GSettings *settings, |
429 | gchar *key, |
430 | MaximusApp *app) |
431 | { |
432 | MaximusAppPrivate *priv; |
433 | |
434 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
435 | priv = app->priv; |
436 | |
437 | if (priv->exclude_class_list) |
438 | g_strfreev (priv->exclude_class_list); |
439 | |
440 | priv->exclude_class_list= g_settings_get_strv (settings, |
441 | APP_EXCLUDE_CLASS"exclude-class"); |
442 | } |
443 | |
444 | static gboolean |
445 | show_desktop (WnckScreen *screen) |
446 | { |
447 | g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((screen)); GType __t = ((wnck_screen_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "WNCK_IS_SCREEN (screen)"); return ((0)); } } while (0); |
448 | |
449 | wnck_screen_toggle_showing_desktop (screen, TRUE(!(0))); |
450 | return FALSE(0); |
451 | } |
452 | |
453 | static void |
454 | on_app_undecorate_changed (GSettings *settings, |
455 | gchar *key, |
456 | MaximusApp *app) |
457 | { |
458 | MaximusAppPrivate *priv; |
459 | GList *windows, *w; |
460 | |
461 | g_return_if_fail (MAXIMUS_IS_APP (app))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((app)); GType __t = ((maximus_app_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_APP (app)"); return; } } while (0); |
462 | priv = app->priv; |
463 | g_return_if_fail (WNCK_IS_SCREEN (priv->screen))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((priv->screen)); GType __t = ((wnck_screen_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_ ; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "WNCK_IS_SCREEN (priv->screen)" ); return; } } while (0); |
464 | |
465 | priv->undecorate = g_settings_get_boolean (settings, APP_UNDECORATE"undecorate"); |
466 | g_debug ("%s\n", priv->undecorate ? "Undecorating" : "Decorating"); |
467 | |
468 | windows = wnck_screen_get_windows (priv->screen); |
469 | for (w = windows; w; w = w->next) |
470 | { |
471 | WnckWindow *window = w->data; |
472 | |
473 | if (!WNCK_IS_WINDOW (window)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (window)); GType __t = ((wnck_window_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) |
474 | continue; |
475 | |
476 | if (no_maximize || priv->no_maximize) |
477 | { |
478 | if (!wnck_window_is_maximized(window)) |
479 | continue; |
480 | } |
481 | |
482 | if (!is_excluded (app, window)) |
483 | { |
484 | GdkDisplay *gdk_display = gdk_display_get_default (); |
485 | |
486 | gdk_x11_display_error_trap_push (gdk_display); |
487 | _window_set_decorations (window, priv->undecorate ? 0 : 1); |
488 | wnck_window_unmaximize (window); |
489 | wnck_window_maximize (window); |
490 | gdk_display_flush (gdk_display); |
491 | gdk_x11_display_error_trap_pop_ignored (gdk_display); |
492 | |
493 | sleep (1); |
494 | } |
495 | } |
496 | /* We want the user to be left on the launcher/desktop after switching modes*/ |
497 | g_timeout_add_seconds (1, (GSourceFunc)show_desktop, priv->screen); |
498 | } |
499 | |
500 | |
501 | /* GObject stuff */ |
502 | static void |
503 | maximus_app_class_init (MaximusAppClass *klass) |
504 | { |
505 | } |
506 | |
507 | static void |
508 | maximus_app_init (MaximusApp *app) |
509 | { |
510 | MaximusAppPrivate *priv; |
511 | WnckScreen *screen; |
512 | |
513 | priv = app->priv = maximus_app_get_instance_private (app); |
514 | |
515 | priv->bind = maximus_bind_get_default (); |
516 | |
517 | was_decorated = g_quark_from_static_string ("was-decorated"); |
518 | |
519 | priv->settings = g_settings_new (APP_SCHEMA"org.mate.maximus"); |
520 | |
521 | g_signal_connect (priv->settings, "changed::" APP_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "exclude-class" ), (((GCallback) (on_exclude_class_changed))), (app), ((void* )0), (GConnectFlags) 0) |
522 | G_CALLBACK (on_exclude_class_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "exclude-class" ), (((GCallback) (on_exclude_class_changed))), (app), ((void* )0), (GConnectFlags) 0); |
523 | g_signal_connect (priv->settings, "changed::" APP_UNDECORATE,g_signal_connect_data ((priv->settings), ("changed::" "undecorate" ), (((GCallback) (on_app_undecorate_changed))), (app), ((void *)0), (GConnectFlags) 0) |
524 | G_CALLBACK (on_app_undecorate_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "undecorate" ), (((GCallback) (on_app_undecorate_changed))), (app), ((void *)0), (GConnectFlags) 0); |
525 | g_signal_connect (priv->settings, "changed::" APP_NO_MAXIMIZE,g_signal_connect_data ((priv->settings), ("changed::" "no-maximize" ), (((GCallback) (on_app_no_maximize_changed))), (app), ((void *)0), (GConnectFlags) 0) |
526 | G_CALLBACK (on_app_no_maximize_changed), app)g_signal_connect_data ((priv->settings), ("changed::" "no-maximize" ), (((GCallback) (on_app_no_maximize_changed))), (app), ((void *)0), (GConnectFlags) 0); |
527 | |
528 | priv->exclude_class_list = g_settings_get_strv (priv->settings, APP_EXCLUDE_CLASS"exclude-class"); |
529 | priv->undecorate = g_settings_get_boolean (priv->settings, APP_UNDECORATE"undecorate"); |
530 | priv->no_maximize = g_settings_get_boolean (priv->settings, APP_NO_MAXIMIZE"no-maximize"); |
531 | g_print ("no maximize: %s\n", priv->no_maximize ? "true" : "false"); |
532 | |
533 | priv->screen = screen = wnck_screen_get_default (); |
534 | g_signal_connect (screen, "window-opened",g_signal_connect_data ((screen), ("window-opened"), (((GCallback ) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0) |
535 | G_CALLBACK (on_window_opened), app)g_signal_connect_data ((screen), ("window-opened"), (((GCallback ) (on_window_opened))), (app), ((void*)0), (GConnectFlags) 0); |
536 | } |
537 | |
538 | MaximusApp * |
539 | maximus_app_get_default (void) |
540 | |
541 | { |
542 | static MaximusApp *app = NULL((void*)0); |
543 | |
544 | if (!app) |
545 | app = g_object_new (MAXIMUS_TYPE_APP(maximus_app_get_type ()), |
546 | NULL((void*)0)); |
547 | |
548 | return app; |
549 | } |
File: | eggaccelerators.c |
Warning: | line 414, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 419, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 424, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | maximus-bind.c |
Warning: | line 467, column 18 Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen' |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* |
2 | * Copyright (C) 2008 Canonical Ltd |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * |
5 | * This program is free software: you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License version 3 as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authored by Neil Jagdish Patel <neil.patel@canonical.com> |
18 | * |
19 | */ |
20 | |
21 | #include <stdio.h> |
22 | #include <string.h> |
23 | |
24 | #include <gtk/gtk.h> |
25 | #include <gdk/gdkx.h> |
26 | |
27 | #include <gdk/gdkkeysyms.h> |
28 | |
29 | #include <gio/gio.h> |
30 | |
31 | #define WNCK_I_KNOW_THIS_IS_UNSTABLE |
32 | #include <libwnck/libwnck.h> |
33 | |
34 | #include <X11/Xlib.h> |
35 | #include <X11/Xresource.h> |
36 | #include <X11/Xutil.h> |
37 | #include <X11/extensions/XTest.h> |
38 | #include <X11/keysymdef.h> |
39 | #include <X11/keysym.h> |
40 | |
41 | #include <fakekey/fakekey.h> |
42 | |
43 | #include "maximus-bind.h" |
44 | |
45 | #include "tomboykeybinder.h" |
46 | #include "eggaccelerators.h" |
47 | |
48 | #define KEY_RELEASE_TIMEOUT300 300 |
49 | #define STATE_CHANGED_SLEEP0.5 0.5 |
50 | |
51 | /* GSettings schemas and keys */ |
52 | #define BIND_SCHEMA"org.mate.maximus" "org.mate.maximus" |
53 | #define BIND_EXCLUDE_CLASS"binding" "binding" |
54 | |
55 | #define SYSRULESDIR"/usr/local/etc""/maximus" SYSCONFDIR"/usr/local/etc""/maximus" |
56 | |
57 | #ifdef __GNUC__4 |
58 | #define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused)) |
59 | #else |
60 | #define UNUSED_VARIABLE__attribute__ ((unused)) |
61 | #endif |
62 | |
63 | struct _MaximusBindPrivate |
64 | { |
65 | FakeKey *fk; |
66 | WnckScreen *screen; |
67 | GSettings *settings; |
68 | |
69 | gchar *binding; |
70 | |
71 | GList *rules; |
72 | }; |
73 | |
74 | typedef struct |
75 | { |
76 | gchar *wm_class; |
77 | gchar *fullscreen; |
78 | gchar *unfullscreen; |
79 | } MaximusRule; |
80 | |
81 | G_DEFINE_TYPE_WITH_PRIVATE (MaximusBind, maximus_bind, G_TYPE_OBJECT)static void maximus_bind_init (MaximusBind *self); static void maximus_bind_class_init (MaximusBindClass *klass); static GType maximus_bind_get_type_once (void); static gpointer maximus_bind_parent_class = ((void*)0); static gint MaximusBind_private_offset; static void maximus_bind_class_intern_init (gpointer klass) { maximus_bind_parent_class = g_type_class_peek_parent (klass); if (MaximusBind_private_offset != 0) g_type_class_adjust_private_offset (klass, &MaximusBind_private_offset ); maximus_bind_class_init ((MaximusBindClass*) klass); } __attribute__ ((__unused__)) static inline gpointer maximus_bind_get_instance_private (MaximusBind *self) { return (((gpointer) ((guint8*) (self) + (glong) (MaximusBind_private_offset)))); } GType maximus_bind_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = maximus_bind_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__((noinline)) static GType maximus_bind_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("MaximusBind" ), sizeof (MaximusBindClass), (GClassInitFunc)(void (*)(void) ) maximus_bind_class_intern_init, sizeof (MaximusBind), (GInstanceInitFunc )(void (*)(void)) maximus_bind_init, (GTypeFlags) 0); { {{ MaximusBind_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (MaximusBindPrivate )); };} } return g_define_type_id; }; |
82 | |
83 | static const gchar * |
84 | get_fullscreen_keystroke (GList *rules, WnckWindow *window) |
85 | { |
86 | WnckClassGroup *group; |
87 | const gchar *class_name; |
88 | GList *r; |
89 | |
90 | group = wnck_window_get_class_group (window); |
91 | class_name = wnck_class_group_get_name (group); |
92 | |
93 | g_debug ("Searching rules for %s:\n", wnck_window_get_name (window)); |
94 | |
95 | for (r = rules; r; r = r->next) |
96 | { |
97 | MaximusRule *rule = r->data; |
98 | |
99 | g_debug ("\t%s ?= %s", class_name, rule->wm_class); |
100 | |
101 | if (class_name && rule->wm_class && strstr (class_name, rule->wm_class)) |
102 | { |
103 | g_debug ("\tYES!\n"); |
104 | return rule->fullscreen; |
105 | } |
106 | g_debug ("\tNO!\n"); |
107 | } |
108 | |
109 | return NULL((void*)0); |
110 | } |
111 | |
112 | static const gchar * |
113 | get_unfullscreen_keystroke (GList *rules, WnckWindow *window) |
114 | { |
115 | WnckClassGroup *group; |
116 | const gchar *class_name; |
117 | GList *r; |
118 | |
119 | group = wnck_window_get_class_group (window); |
120 | class_name = wnck_class_group_get_name (group); |
121 | |
122 | for (r = rules; r; r = r->next) |
123 | { |
124 | MaximusRule *rule = r->data; |
125 | |
126 | if (class_name && rule->wm_class && strstr (class_name, rule->wm_class)) |
127 | { |
128 | return rule->unfullscreen; |
129 | } |
130 | } |
131 | |
132 | return NULL((void*)0); |
133 | } |
134 | static gboolean |
135 | real_fullscreen (MaximusBind *bind) |
136 | { |
137 | MaximusBindPrivate *priv; |
138 | GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display; |
139 | WnckWindow *active; |
140 | const gchar *keystroke; |
141 | |
142 | priv = bind->priv; |
143 | |
144 | display = gdk_display_get_default (); |
145 | active = wnck_screen_get_active_window (priv->screen); |
146 | |
147 | if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (active)); GType __t = ((wnck_window_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) |
148 | || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL) |
149 | return FALSE(0); |
150 | |
151 | keystroke = get_fullscreen_keystroke (priv->rules, active); |
152 | |
153 | if (keystroke) |
154 | { |
155 | guint keysym = 0; |
156 | EggVirtualModifierType modifiers = 0; |
157 | |
158 | if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers)) |
159 | { |
160 | guint mods = 0; |
161 | |
162 | if (modifiers & EGG_VIRTUAL_SHIFT_MASK) |
163 | mods |= FAKEKEYMOD_SHIFT; |
164 | if (modifiers & EGG_VIRTUAL_CONTROL_MASK) |
165 | mods |= FAKEKEYMOD_CONTROL; |
166 | if (modifiers & EGG_VIRTUAL_ALT_MASK) |
167 | mods |= FAKEKEYMOD_ALT; |
168 | if (modifiers & EGG_VIRTUAL_META_MASK) |
169 | mods |= FAKEKEYMOD_META; |
170 | |
171 | g_debug ("Sending fullscreen special event: %s = %d %d", |
172 | keystroke, keysym, mods); |
173 | fakekey_press_keysym (priv->fk, keysym, mods); |
174 | fakekey_release (priv->fk); |
175 | |
176 | return FALSE(0); |
177 | } |
178 | } |
179 | |
180 | if (!wnck_window_is_fullscreen (active)) |
181 | { |
182 | g_debug ("Sending fullscreen F11 event"); |
183 | fakekey_press_keysym (priv->fk, XK_F110xffc8, 0); |
184 | fakekey_release (priv->fk); |
185 | } |
186 | |
187 | sleep (STATE_CHANGED_SLEEP0.5); |
188 | |
189 | if (!wnck_window_is_fullscreen (active)) |
190 | { |
191 | g_debug ("Forcing fullscreen wnck event"); |
192 | wnck_window_set_fullscreen (active, TRUE(!(0))); |
193 | } |
194 | |
195 | return FALSE(0); |
196 | } |
197 | |
198 | static void |
199 | fullscreen (MaximusBind *bind, WnckWindow *window) |
200 | { |
201 | MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv; |
202 | |
203 | priv = bind->priv; |
204 | |
205 | g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_fullscreen, bind); |
206 | } |
207 | |
208 | static gboolean |
209 | real_unfullscreen (MaximusBind *bind) |
210 | { |
211 | MaximusBindPrivate *priv; |
212 | GdkDisplay UNUSED_VARIABLE__attribute__ ((unused)) *display; |
213 | WnckWindow *active; |
214 | const gchar *keystroke; |
215 | |
216 | priv = bind->priv; |
217 | |
218 | display = gdk_display_get_default (); |
219 | active = wnck_screen_get_active_window (priv->screen); |
220 | |
221 | if (!WNCK_IS_WINDOW (active)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (active)); GType __t = ((wnck_window_get_type ())); gboolean __r ; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) |
222 | || wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL) |
223 | return FALSE(0); |
224 | |
225 | keystroke = get_unfullscreen_keystroke (priv->rules, active); |
226 | |
227 | if (keystroke) |
228 | { |
229 | guint keysym = 0; |
230 | EggVirtualModifierType modifiers = 0; |
231 | |
232 | if (egg_accelerator_parse_virtual (keystroke, &keysym, &modifiers)) |
233 | { |
234 | guint mods = 0; |
235 | |
236 | if (modifiers & EGG_VIRTUAL_SHIFT_MASK) |
237 | mods |= FAKEKEYMOD_SHIFT; |
238 | if (modifiers & EGG_VIRTUAL_CONTROL_MASK) |
239 | mods |= FAKEKEYMOD_CONTROL; |
240 | if (modifiers & EGG_VIRTUAL_ALT_MASK) |
241 | mods |= FAKEKEYMOD_ALT; |
242 | if (modifiers & EGG_VIRTUAL_META_MASK) |
243 | mods |= FAKEKEYMOD_META; |
244 | |
245 | g_debug ("Sending fullscreen special event: %s = %d %d", |
246 | keystroke, keysym, mods); |
247 | fakekey_press_keysym (priv->fk, keysym, mods); |
248 | fakekey_release (priv->fk); |
249 | |
250 | return FALSE(0); |
251 | } |
252 | } |
253 | if (wnck_window_is_fullscreen (active)) |
254 | { |
255 | g_debug ("Sending un-fullscreen F11 event"); |
256 | fakekey_press_keysym (priv->fk, XK_F110xffc8, 0); |
257 | fakekey_release (priv->fk); |
258 | } |
259 | |
260 | sleep (STATE_CHANGED_SLEEP0.5); |
261 | |
262 | if (wnck_window_is_fullscreen (active)) |
263 | { |
264 | g_debug ("Forcing un-fullscreen wnck event"); |
265 | wnck_window_set_fullscreen (active, FALSE(0)); |
266 | } |
267 | |
268 | return FALSE(0); |
269 | } |
270 | |
271 | static void |
272 | unfullscreen (MaximusBind *bind, WnckWindow *window) |
273 | { |
274 | MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv; |
275 | |
276 | priv = bind->priv; |
277 | |
278 | g_timeout_add (KEY_RELEASE_TIMEOUT300, (GSourceFunc)real_unfullscreen, bind); |
279 | } |
280 | |
281 | |
282 | static void |
283 | on_binding_activated (gchar *keystring, MaximusBind *bind) |
284 | { |
285 | MaximusBindPrivate *priv; |
286 | WnckWindow *active; |
287 | |
288 | g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while ( 0); |
289 | priv = bind->priv; |
290 | |
291 | active = wnck_screen_get_active_window (priv->screen); |
292 | |
293 | if (wnck_window_get_window_type (active) != WNCK_WINDOW_NORMAL) |
294 | return; |
295 | |
296 | if (wnck_window_is_fullscreen (active)) |
297 | { |
298 | unfullscreen (bind, active); |
299 | } |
300 | else |
301 | { |
302 | fullscreen (bind, active); |
303 | } |
304 | } |
305 | |
306 | /* Callbacks */ |
307 | static gboolean |
308 | binding_is_valid (const gchar *binding) |
309 | { |
310 | gboolean retval = TRUE(!(0)); |
311 | |
312 | if (!binding || strlen (binding) < 1 || strcmp (binding, "disabled") == 0) |
313 | retval = FALSE(0); |
314 | |
315 | return retval; |
316 | } |
317 | |
318 | static void |
319 | on_binding_changed (GSettings *settings, |
320 | gchar *key, |
321 | MaximusBind *bind) |
322 | { |
323 | MaximusBindPrivate *priv; |
324 | |
325 | g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while ( 0); |
326 | priv = bind->priv; |
327 | |
328 | if (binding_is_valid (priv->binding)) |
329 | tomboy_keybinder_unbind (priv->binding, |
330 | (TomboyBindkeyHandler)on_binding_changed); |
331 | g_free (priv->binding); |
332 | |
333 | priv->binding = g_settings_get_string (settings, BIND_EXCLUDE_CLASS"binding"); |
334 | |
335 | if (binding_is_valid (priv->binding)) |
336 | tomboy_keybinder_bind (priv->binding, |
337 | (TomboyBindkeyHandler)on_binding_activated, |
338 | bind); |
339 | |
340 | g_print ("Binding changed: %s\n", priv->binding); |
341 | } |
342 | |
343 | |
344 | /* GObject stuff */ |
345 | static void |
346 | create_rule (MaximusBind *bind, const gchar *filename) |
347 | { |
348 | #define RULE_GROUP"Fullscreening" "Fullscreening" |
349 | #define RULE_WMCLASS"WMClass" "WMClass" |
350 | #define RULE_FULLSCREEN"Fullscreen" "Fullscreen" |
351 | #define RULE_UNFULLSCREEN"Unfullscreen" "Unfullscreen" |
352 | MaximusBindPrivate *priv; |
353 | GKeyFile *file; |
354 | GError *error = NULL((void*)0); |
355 | MaximusRule *rule; |
356 | |
357 | priv = bind->priv; |
358 | |
359 | file = g_key_file_new (); |
360 | g_key_file_load_from_file (file, filename, 0, &error); |
361 | if (error) |
362 | { |
363 | g_warning ("Unable to load %s: %s\n", filename, error->message); |
364 | g_error_free (error); |
365 | g_key_file_free (file); |
366 | return; |
367 | } |
368 | |
369 | rule = g_slice_new0 (MaximusRule)(MaximusRule *) (__extension__ ({ gsize __s = sizeof (MaximusRule ); gpointer __p; __p = g_slice_alloc (__s); memset (__p, 0, __s ); __p; })); |
370 | |
371 | rule->wm_class = g_key_file_get_string (file, |
372 | RULE_GROUP"Fullscreening", RULE_WMCLASS"WMClass", |
373 | NULL((void*)0)); |
374 | rule->fullscreen = g_key_file_get_string (file, |
375 | RULE_GROUP"Fullscreening", RULE_FULLSCREEN"Fullscreen", |
376 | NULL((void*)0)); |
377 | rule->unfullscreen = g_key_file_get_string (file, |
378 | RULE_GROUP"Fullscreening", RULE_UNFULLSCREEN"Unfullscreen", |
379 | NULL((void*)0)); |
380 | if (!rule->wm_class || !rule->fullscreen || !rule->unfullscreen) |
381 | { |
382 | g_free (rule->wm_class); |
383 | g_free (rule->fullscreen); |
384 | g_free (rule->unfullscreen); |
385 | g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else (void) ((MaximusRule*) 0 == (rule)); } while (0); |
386 | |
387 | g_warning ("Unable to load %s, missing strings", filename); |
388 | } |
389 | else |
390 | priv->rules = g_list_append (priv->rules, rule); |
391 | |
392 | g_key_file_free (file); |
393 | } |
394 | |
395 | static void |
396 | load_rules (MaximusBind *bind, const gchar *path) |
397 | { |
398 | MaximusBindPrivate UNUSED_VARIABLE__attribute__ ((unused)) *priv; |
399 | GDir *dir; |
400 | const gchar *name; |
401 | |
402 | priv = bind->priv; |
403 | |
404 | dir = g_dir_open (path, 0, NULL((void*)0)); |
405 | |
406 | if (!dir) |
407 | return; |
408 | |
409 | while ((name = g_dir_read_name (dir))) |
410 | { |
411 | gchar *filename; |
412 | |
413 | filename= g_build_filename (path, name, NULL((void*)0)); |
414 | |
415 | create_rule (bind, filename); |
416 | |
417 | g_free (filename); |
418 | } |
419 | |
420 | |
421 | g_dir_close (dir); |
422 | } |
423 | |
424 | static void |
425 | maximus_bind_finalize (GObject *obj) |
426 | { |
427 | MaximusBind *bind = MAXIMUS_BIND (obj)((((MaximusBind*) g_type_check_instance_cast ((GTypeInstance* ) ((obj)), ((maximus_bind_get_type ())))))); |
428 | MaximusBindPrivate *priv; |
429 | GList *r; |
430 | |
431 | g_return_if_fail (MAXIMUS_IS_BIND (bind))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((bind)); GType __t = ((maximus_bind_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "MAXIMUS_IS_BIND (bind)"); return; } } while ( 0); |
432 | priv = bind->priv; |
433 | |
434 | for (r = priv->rules; r; r = r->next) |
435 | { |
436 | MaximusRule *rule = r->data; |
437 | |
438 | g_free (rule->wm_class); |
439 | g_free (rule->fullscreen); |
440 | g_free (rule->unfullscreen); |
441 | |
442 | g_slice_free (MaximusRule, rule)do { if (1) g_slice_free1 (sizeof (MaximusRule), (rule)); else (void) ((MaximusRule*) 0 == (rule)); } while (0); |
443 | } |
444 | g_free (priv->binding); |
445 | |
446 | G_OBJECT_CLASS (maximus_bind_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((maximus_bind_parent_class )), (((GType) ((20) << (2))))))))->finalize (obj); |
447 | } |
448 | |
449 | static void |
450 | maximus_bind_class_init (MaximusBindClass *klass) |
451 | { |
452 | GObjectClass *obj_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass )), (((GType) ((20) << (2)))))))); |
453 | |
454 | obj_class->finalize = maximus_bind_finalize; |
455 | } |
456 | |
457 | static void |
458 | maximus_bind_init (MaximusBind *bind) |
459 | { |
460 | MaximusBindPrivate *priv; |
461 | GdkDisplay *display = gdk_display_get_default (); |
462 | WnckScreen *screen; |
463 | |
464 | priv = bind->priv = maximus_bind_get_instance_private (bind); |
465 | |
466 | priv->fk = fakekey_init (GDK_DISPLAY_XDISPLAY (display)(gdk_x11_display_get_xdisplay (display))); |
467 | priv->screen = screen = wnck_screen_get_default (); |
Although the value stored to 'screen' is used in the enclosing expression, the value is never actually read from 'screen' | |
468 | priv->rules = NULL((void*)0); |
469 | priv->settings = g_settings_new (BIND_SCHEMA"org.mate.maximus"); |
470 | |
471 | tomboy_keybinder_init (); |
472 | |
473 | g_signal_connect (priv->settings, "changed::" BIND_EXCLUDE_CLASS,g_signal_connect_data ((priv->settings), ("changed::" "binding" ), (((GCallback) (on_binding_changed))), (bind), ((void*)0), ( GConnectFlags) 0) |
474 | G_CALLBACK (on_binding_changed), bind)g_signal_connect_data ((priv->settings), ("changed::" "binding" ), (((GCallback) (on_binding_changed))), (bind), ((void*)0), ( GConnectFlags) 0); |
475 | |
476 | priv->binding = g_settings_get_string (priv->settings, BIND_EXCLUDE_CLASS"binding"); |
477 | |
478 | if (binding_is_valid (priv->binding)) |
479 | tomboy_keybinder_bind (priv->binding, |
480 | (TomboyBindkeyHandler)on_binding_activated, |
481 | bind); |
482 | |
483 | load_rules (bind, SYSRULESDIR"/usr/local/etc""/maximus"); |
484 | } |
485 | |
486 | MaximusBind * |
487 | maximus_bind_get_default (void) |
488 | |
489 | { |
490 | static MaximusBind *bind = NULL((void*)0); |
491 | |
492 | if (!bind) |
493 | bind = g_object_new (MAXIMUS_TYPE_BIND(maximus_bind_get_type ()), |
494 | NULL((void*)0)); |
495 | |
496 | return bind; |
497 | } |
File: | eggaccelerators.c |
Warning: | line 444, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |
File: | eggaccelerators.c |
Warning: | line 434, column 7 Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 |
Press '?' + to see keyboard shortcuts
+ + +Keyboard shortcuts:
+1 | /* eggaccelerators.c |
2 | * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik |
3 | * Copyright (C) 2012-2021 MATE Developers |
4 | * Developed by Havoc Pennington, Tim Janik |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA |
19 | */ |
20 | |
21 | #include "eggaccelerators.h" |
22 | |
23 | #include <string.h> |
24 | #include <gdk/gdkx.h> |
25 | #include <gdk/gdkkeysyms.h> |
26 | |
27 | enum |
28 | { |
29 | EGG_MODMAP_ENTRY_SHIFT = 0, |
30 | EGG_MODMAP_ENTRY_LOCK = 1, |
31 | EGG_MODMAP_ENTRY_CONTROL = 2, |
32 | EGG_MODMAP_ENTRY_MOD1 = 3, |
33 | EGG_MODMAP_ENTRY_MOD2 = 4, |
34 | EGG_MODMAP_ENTRY_MOD3 = 5, |
35 | EGG_MODMAP_ENTRY_MOD4 = 6, |
36 | EGG_MODMAP_ENTRY_MOD5 = 7, |
37 | EGG_MODMAP_ENTRY_LAST = 8 |
38 | }; |
39 | |
40 | #define MODMAP_ENTRY_TO_MODIFIER(x)(1 << (x)) (1 << (x)) |
41 | |
42 | typedef struct |
43 | { |
44 | EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; |
45 | |
46 | } EggModmap; |
47 | |
48 | const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); |
49 | |
50 | static inline gboolean |
51 | is_alt (const gchar *string) |
52 | { |
53 | return ((string[0] == '<') && |
54 | (string[1] == 'a' || string[1] == 'A') && |
55 | (string[2] == 'l' || string[2] == 'L') && |
56 | (string[3] == 't' || string[3] == 'T') && |
57 | (string[4] == '>')); |
58 | } |
59 | |
60 | static inline gboolean |
61 | is_ctl (const gchar *string) |
62 | { |
63 | return ((string[0] == '<') && |
64 | (string[1] == 'c' || string[1] == 'C') && |
65 | (string[2] == 't' || string[2] == 'T') && |
66 | (string[3] == 'l' || string[3] == 'L') && |
67 | (string[4] == '>')); |
68 | } |
69 | |
70 | static inline gboolean |
71 | is_modx (const gchar *string) |
72 | { |
73 | return ((string[0] == '<') && |
74 | (string[1] == 'm' || string[1] == 'M') && |
75 | (string[2] == 'o' || string[2] == 'O') && |
76 | (string[3] == 'd' || string[3] == 'D') && |
77 | (string[4] >= '1' && string[4] <= '5') && |
78 | (string[5] == '>')); |
79 | } |
80 | |
81 | static inline gboolean |
82 | is_ctrl (const gchar *string) |
83 | { |
84 | return ((string[0] == '<') && |
85 | (string[1] == 'c' || string[1] == 'C') && |
86 | (string[2] == 't' || string[2] == 'T') && |
87 | (string[3] == 'r' || string[3] == 'R') && |
88 | (string[4] == 'l' || string[4] == 'L') && |
89 | (string[5] == '>')); |
90 | } |
91 | |
92 | static inline gboolean |
93 | is_shft (const gchar *string) |
94 | { |
95 | return ((string[0] == '<') && |
96 | (string[1] == 's' || string[1] == 'S') && |
97 | (string[2] == 'h' || string[2] == 'H') && |
98 | (string[3] == 'f' || string[3] == 'F') && |
99 | (string[4] == 't' || string[4] == 'T') && |
100 | (string[5] == '>')); |
101 | } |
102 | |
103 | static inline gboolean |
104 | is_shift (const gchar *string) |
105 | { |
106 | return ((string[0] == '<') && |
107 | (string[1] == 's' || string[1] == 'S') && |
108 | (string[2] == 'h' || string[2] == 'H') && |
109 | (string[3] == 'i' || string[3] == 'I') && |
110 | (string[4] == 'f' || string[4] == 'F') && |
111 | (string[5] == 't' || string[5] == 'T') && |
112 | (string[6] == '>')); |
113 | } |
114 | |
115 | static inline gboolean |
116 | is_control (const gchar *string) |
117 | { |
118 | return ((string[0] == '<') && |
119 | (string[1] == 'c' || string[1] == 'C') && |
120 | (string[2] == 'o' || string[2] == 'O') && |
121 | (string[3] == 'n' || string[3] == 'N') && |
122 | (string[4] == 't' || string[4] == 'T') && |
123 | (string[5] == 'r' || string[5] == 'R') && |
124 | (string[6] == 'o' || string[6] == 'O') && |
125 | (string[7] == 'l' || string[7] == 'L') && |
126 | (string[8] == '>')); |
127 | } |
128 | |
129 | static inline gboolean |
130 | is_release (const gchar *string) |
131 | { |
132 | return ((string[0] == '<') && |
133 | (string[1] == 'r' || string[1] == 'R') && |
134 | (string[2] == 'e' || string[2] == 'E') && |
135 | (string[3] == 'l' || string[3] == 'L') && |
136 | (string[4] == 'e' || string[4] == 'E') && |
137 | (string[5] == 'a' || string[5] == 'A') && |
138 | (string[6] == 's' || string[6] == 'S') && |
139 | (string[7] == 'e' || string[7] == 'E') && |
140 | (string[8] == '>')); |
141 | } |
142 | |
143 | static inline gboolean |
144 | is_meta (const gchar *string) |
145 | { |
146 | return ((string[0] == '<') && |
147 | (string[1] == 'm' || string[1] == 'M') && |
148 | (string[2] == 'e' || string[2] == 'E') && |
149 | (string[3] == 't' || string[3] == 'T') && |
150 | (string[4] == 'a' || string[4] == 'A') && |
151 | (string[5] == '>')); |
152 | } |
153 | |
154 | static inline gboolean |
155 | is_super (const gchar *string) |
156 | { |
157 | return ((string[0] == '<') && |
158 | (string[1] == 's' || string[1] == 'S') && |
159 | (string[2] == 'u' || string[2] == 'U') && |
160 | (string[3] == 'p' || string[3] == 'P') && |
161 | (string[4] == 'e' || string[4] == 'E') && |
162 | (string[5] == 'r' || string[5] == 'R') && |
163 | (string[6] == '>')); |
164 | } |
165 | |
166 | static inline gboolean |
167 | is_hyper (const gchar *string) |
168 | { |
169 | return ((string[0] == '<') && |
170 | (string[1] == 'h' || string[1] == 'H') && |
171 | (string[2] == 'y' || string[2] == 'Y') && |
172 | (string[3] == 'p' || string[3] == 'P') && |
173 | (string[4] == 'e' || string[4] == 'E') && |
174 | (string[5] == 'r' || string[5] == 'R') && |
175 | (string[6] == '>')); |
176 | } |
177 | |
178 | /** |
179 | * egg_accelerator_parse_virtual: |
180 | * @accelerator: string representing an accelerator |
181 | * @accelerator_key: return location for accelerator keyval |
182 | * @accelerator_mods: return location for accelerator modifier mask |
183 | * |
184 | * Parses a string representing a virtual accelerator. The format |
185 | * looks like "<Control>a" or "<Shift><Alt>F1" or |
186 | * "<Release>z" (the last one is for key release). The parser |
187 | * is fairly liberal and allows lower or upper case, and also |
188 | * abbreviations such as "<Ctl>" and "<Ctrl>". |
189 | * |
190 | * If the parse fails, @accelerator_key and @accelerator_mods will |
191 | * be set to 0 (zero) and %FALSE will be returned. If the string contains |
192 | * only modifiers, @accelerator_key will be set to 0 but %TRUE will be |
193 | * returned. |
194 | * |
195 | * The virtual vs. concrete accelerator distinction is a relic of |
196 | * how the X Window System works; there are modifiers Mod2-Mod5 that |
197 | * can represent various keyboard keys (numlock, meta, hyper, etc.), |
198 | * the virtual modifier represents the keyboard key, the concrete |
199 | * modifier the actual Mod2-Mod5 bits in the key press event. |
200 | * |
201 | * Returns: %TRUE on success. |
202 | */ |
203 | gboolean |
204 | egg_accelerator_parse_virtual (const gchar *accelerator, |
205 | guint *accelerator_key, |
206 | EggVirtualModifierType *accelerator_mods) |
207 | { |
208 | guint keyval; |
209 | GdkModifierType mods; |
210 | gint len; |
211 | gboolean bad_keyval; |
212 | |
213 | if (accelerator_key) |
214 | *accelerator_key = 0; |
215 | if (accelerator_mods) |
216 | *accelerator_mods = 0; |
217 | |
218 | g_return_val_if_fail (accelerator != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (accelerator != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "accelerator != NULL" ); return ((0)); } } while (0); |
219 | |
220 | bad_keyval = FALSE(0); |
221 | |
222 | keyval = 0; |
223 | mods = 0; |
224 | len = strlen (accelerator); |
225 | while (len) |
226 | { |
227 | if (*accelerator == '<') |
228 | { |
229 | if (len >= 9 && is_release (accelerator)) |
230 | { |
231 | accelerator += 9; |
232 | len -= 9; |
233 | mods |= EGG_VIRTUAL_RELEASE_MASK; |
234 | } |
235 | else if (len >= 9 && is_control (accelerator)) |
236 | { |
237 | accelerator += 9; |
238 | len -= 9; |
239 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
240 | } |
241 | else if (len >= 7 && is_shift (accelerator)) |
242 | { |
243 | accelerator += 7; |
244 | len -= 7; |
245 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
246 | } |
247 | else if (len >= 6 && is_shft (accelerator)) |
248 | { |
249 | accelerator += 6; |
250 | len -= 6; |
251 | mods |= EGG_VIRTUAL_SHIFT_MASK; |
252 | } |
253 | else if (len >= 6 && is_ctrl (accelerator)) |
254 | { |
255 | accelerator += 6; |
256 | len -= 6; |
257 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
258 | } |
259 | else if (len >= 6 && is_modx (accelerator)) |
260 | { |
261 | static const guint mod_vals[] = { |
262 | EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, |
263 | EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK |
264 | }; |
265 | |
266 | len -= 6; |
267 | accelerator += 4; |
268 | mods |= mod_vals[*accelerator - '1']; |
269 | accelerator += 2; |
270 | } |
271 | else if (len >= 5 && is_ctl (accelerator)) |
272 | { |
273 | accelerator += 5; |
274 | len -= 5; |
275 | mods |= EGG_VIRTUAL_CONTROL_MASK; |
276 | } |
277 | else if (len >= 5 && is_alt (accelerator)) |
278 | { |
279 | accelerator += 5; |
280 | len -= 5; |
281 | mods |= EGG_VIRTUAL_ALT_MASK; |
282 | } |
283 | else if (len >= 6 && is_meta (accelerator)) |
284 | { |
285 | accelerator += 6; |
286 | len -= 6; |
287 | mods |= EGG_VIRTUAL_META_MASK; |
288 | } |
289 | else if (len >= 7 && is_hyper (accelerator)) |
290 | { |
291 | accelerator += 7; |
292 | len -= 7; |
293 | mods |= EGG_VIRTUAL_HYPER_MASK; |
294 | } |
295 | else if (len >= 7 && is_super (accelerator)) |
296 | { |
297 | accelerator += 7; |
298 | len -= 7; |
299 | mods |= EGG_VIRTUAL_SUPER_MASK; |
300 | } |
301 | else |
302 | { |
303 | gchar last_ch; |
304 | |
305 | last_ch = *accelerator; |
306 | while (last_ch && last_ch != '>') |
307 | { |
308 | last_ch = *accelerator; |
309 | accelerator += 1; |
310 | len -= 1; |
311 | } |
312 | } |
313 | } |
314 | else |
315 | { |
316 | keyval = gdk_keyval_from_name (accelerator); |
317 | |
318 | if (keyval == 0) |
319 | bad_keyval = TRUE(!(0)); |
320 | |
321 | accelerator += len; |
322 | len -= len; |
323 | } |
324 | } |
325 | |
326 | if (accelerator_key) |
327 | *accelerator_key = gdk_keyval_to_lower (keyval); |
328 | if (accelerator_mods) |
329 | *accelerator_mods = mods; |
330 | |
331 | return !bad_keyval; |
332 | } |
333 | |
334 | |
335 | /** |
336 | * egg_virtual_accelerator_name: |
337 | * @accelerator_key: accelerator keyval |
338 | * @accelerator_mods: accelerator modifier mask |
339 | * @returns: a newly-allocated accelerator name |
340 | * |
341 | * Converts an accelerator keyval and modifier mask |
342 | * into a string parseable by egg_accelerator_parse_virtual(). |
343 | * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, |
344 | * this function returns "<Control>q". |
345 | * |
346 | * The caller of this function must free the returned string. |
347 | */ |
348 | gchar* |
349 | egg_virtual_accelerator_name (guint accelerator_key, |
350 | EggVirtualModifierType accelerator_mods) |
351 | { |
352 | static const gchar text_release[] = "<Release>"; |
353 | static const gchar text_shift[] = "<Shift>"; |
354 | static const gchar text_control[] = "<Control>"; |
355 | static const gchar text_mod1[] = "<Alt>"; |
356 | static const gchar text_mod2[] = "<Mod2>"; |
357 | static const gchar text_mod3[] = "<Mod3>"; |
358 | static const gchar text_mod4[] = "<Mod4>"; |
359 | static const gchar text_mod5[] = "<Mod5>"; |
360 | static const gchar text_meta[] = "<Meta>"; |
361 | static const gchar text_super[] = "<Super>"; |
362 | static const gchar text_hyper[] = "<Hyper>"; |
363 | guint l; |
364 | gchar *keyval_name; |
365 | gchar *accelerator; |
366 | |
367 | accelerator_mods &= EGG_VIRTUAL_MODIFIER_MASK; |
368 | |
369 | keyval_name = gdk_keyval_name (gdk_keyval_to_lower (accelerator_key)); |
370 | if (!keyval_name) |
371 | keyval_name = ""; |
372 | |
373 | l = 0; |
374 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
375 | l += sizeof (text_release) - 1; |
376 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
377 | l += sizeof (text_shift) - 1; |
378 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
379 | l += sizeof (text_control) - 1; |
380 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
381 | l += sizeof (text_mod1) - 1; |
382 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
383 | l += sizeof (text_mod2) - 1; |
384 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
385 | l += sizeof (text_mod3) - 1; |
386 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
387 | l += sizeof (text_mod4) - 1; |
388 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
389 | l += sizeof (text_mod5) - 1; |
390 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
391 | l += sizeof (text_meta) - 1; |
392 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
393 | l += sizeof (text_hyper) - 1; |
394 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
395 | l += sizeof (text_super) - 1; |
396 | l += strlen (keyval_name); |
397 | |
398 | accelerator = g_new (gchar, l + 1)(gchar *) (__extension__ ({ gsize __n = (gsize) (l + 1); gsize __s = sizeof (gchar); gpointer __p; if (__s == 1) __p = g_malloc (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc (__n * __s); else __p = g_malloc_n (__n, __s); __p; })); |
399 | |
400 | l = 0; |
401 | accelerator[l] = 0; |
402 | if (accelerator_mods & EGG_VIRTUAL_RELEASE_MASK) |
403 | { |
404 | strcpy (accelerator + l, text_release); |
405 | l += sizeof (text_release) - 1; |
406 | } |
407 | if (accelerator_mods & EGG_VIRTUAL_SHIFT_MASK) |
408 | { |
409 | strcpy (accelerator + l, text_shift); |
410 | l += sizeof (text_shift) - 1; |
411 | } |
412 | if (accelerator_mods & EGG_VIRTUAL_CONTROL_MASK) |
413 | { |
414 | strcpy (accelerator + l, text_control); |
415 | l += sizeof (text_control) - 1; |
416 | } |
417 | if (accelerator_mods & EGG_VIRTUAL_ALT_MASK) |
418 | { |
419 | strcpy (accelerator + l, text_mod1); |
420 | l += sizeof (text_mod1) - 1; |
421 | } |
422 | if (accelerator_mods & EGG_VIRTUAL_MOD2_MASK) |
423 | { |
424 | strcpy (accelerator + l, text_mod2); |
425 | l += sizeof (text_mod2) - 1; |
426 | } |
427 | if (accelerator_mods & EGG_VIRTUAL_MOD3_MASK) |
428 | { |
429 | strcpy (accelerator + l, text_mod3); |
430 | l += sizeof (text_mod3) - 1; |
431 | } |
432 | if (accelerator_mods & EGG_VIRTUAL_MOD4_MASK) |
433 | { |
434 | strcpy (accelerator + l, text_mod4); |
Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 | |
435 | l += sizeof (text_mod4) - 1; |
436 | } |
437 | if (accelerator_mods & EGG_VIRTUAL_MOD5_MASK) |
438 | { |
439 | strcpy (accelerator + l, text_mod5); |
440 | l += sizeof (text_mod5) - 1; |
441 | } |
442 | if (accelerator_mods & EGG_VIRTUAL_META_MASK) |
443 | { |
444 | strcpy (accelerator + l, text_meta); |
445 | l += sizeof (text_meta) - 1; |
446 | } |
447 | if (accelerator_mods & EGG_VIRTUAL_HYPER_MASK) |
448 | { |
449 | strcpy (accelerator + l, text_hyper); |
450 | l += sizeof (text_hyper) - 1; |
451 | } |
452 | if (accelerator_mods & EGG_VIRTUAL_SUPER_MASK) |
453 | { |
454 | strcpy (accelerator + l, text_super); |
455 | l += sizeof (text_super) - 1; |
456 | } |
457 | |
458 | strcpy (accelerator + l, keyval_name); |
459 | |
460 | return accelerator; |
461 | } |
462 | |
463 | void |
464 | egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, |
465 | EggVirtualModifierType virtual_mods, |
466 | GdkModifierType *concrete_mods) |
467 | { |
468 | GdkModifierType concrete; |
469 | int i; |
470 | const EggModmap *modmap; |
471 | |
472 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
473 | g_return_if_fail (concrete_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (concrete_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "concrete_mods != NULL" ); return; } } while (0); |
474 | |
475 | modmap = egg_keymap_get_modmap (keymap); |
476 | |
477 | /* Not so sure about this algorithm. */ |
478 | |
479 | concrete = 0; |
480 | i = 0; |
481 | while (i < EGG_MODMAP_ENTRY_LAST) |
482 | { |
483 | if (modmap->mapping[i] & virtual_mods) |
484 | concrete |= (1 << i); |
485 | |
486 | ++i; |
487 | } |
488 | |
489 | *concrete_mods = concrete; |
490 | } |
491 | |
492 | void |
493 | egg_keymap_virtualize_modifiers (GdkKeymap *keymap, |
494 | GdkModifierType concrete_mods, |
495 | EggVirtualModifierType *virtual_mods) |
496 | { |
497 | GdkModifierType virtual; |
498 | int i; |
499 | const EggModmap *modmap; |
500 | |
501 | g_return_if_fail (GDK_IS_KEYMAP (keymap))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((keymap)); GType __t = ((gdk_keymap_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char* ) (__func__)), "GDK_IS_KEYMAP (keymap)"); return; } } while ( 0); |
502 | g_return_if_fail (virtual_mods != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (virtual_mods != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "virtual_mods != NULL" ); return; } } while (0); |
503 | |
504 | modmap = egg_keymap_get_modmap (keymap); |
505 | |
506 | /* Not so sure about this algorithm. */ |
507 | |
508 | virtual = 0; |
509 | i = 0; |
510 | while (i < EGG_MODMAP_ENTRY_LAST) |
511 | { |
512 | if ((1 << i) & concrete_mods) |
513 | { |
514 | EggVirtualModifierType cleaned; |
515 | |
516 | cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | |
517 | EGG_VIRTUAL_MOD3_MASK | |
518 | EGG_VIRTUAL_MOD4_MASK | |
519 | EGG_VIRTUAL_MOD5_MASK); |
520 | |
521 | if (cleaned != 0) |
522 | { |
523 | virtual |= cleaned; |
524 | } |
525 | else |
526 | { |
527 | /* Rather than dropping mod2->mod5 if not bound, |
528 | * go ahead and use the concrete names |
529 | */ |
530 | virtual |= modmap->mapping[i]; |
531 | } |
532 | } |
533 | |
534 | ++i; |
535 | } |
536 | |
537 | *virtual_mods = virtual; |
538 | } |
539 | |
540 | static void |
541 | reload_modmap (GdkKeymap *keymap, |
542 | EggModmap *modmap) |
543 | { |
544 | XModifierKeymap *xmodmap; |
545 | int map_size; |
546 | int i; |
547 | |
548 | /* FIXME multihead */ |
549 | xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); |
550 | |
551 | memset (modmap->mapping, 0, sizeof (modmap->mapping)); |
552 | |
553 | /* there are 8 modifiers, and the first 3 are shift, shift lock, |
554 | * and control |
555 | */ |
556 | map_size = 8 * xmodmap->max_keypermod; |
557 | i = 3 * xmodmap->max_keypermod; |
558 | while (i < map_size) |
559 | { |
560 | /* get the key code at this point in the map, |
561 | * see if its keysym is one we're interested in |
562 | */ |
563 | int keycode = xmodmap->modifiermap[i]; |
564 | GdkKeymapKey *keys; |
565 | guint *keyvals; |
566 | int n_entries; |
567 | int j; |
568 | EggVirtualModifierType mask; |
569 | |
570 | keys = NULL((void*)0); |
571 | keyvals = NULL((void*)0); |
572 | n_entries = 0; |
573 | |
574 | gdk_keymap_get_entries_for_keycode (keymap, |
575 | keycode, |
576 | &keys, &keyvals, &n_entries); |
577 | |
578 | mask = 0; |
579 | j = 0; |
580 | while (j < n_entries) |
581 | { |
582 | if (keyvals[j] == GDK_KEY_Num_Lock0xff7f) |
583 | mask |= EGG_VIRTUAL_NUM_LOCK_MASK; |
584 | else if (keyvals[j] == GDK_KEY_Scroll_Lock0xff14) |
585 | mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; |
586 | else if (keyvals[j] == GDK_KEY_Meta_L0xffe7 || |
587 | keyvals[j] == GDK_KEY_Meta_R0xffe8) |
588 | mask |= EGG_VIRTUAL_META_MASK; |
589 | else if (keyvals[j] == GDK_KEY_Hyper_L0xffed || |
590 | keyvals[j] == GDK_KEY_Hyper_R0xffee) |
591 | mask |= EGG_VIRTUAL_HYPER_MASK; |
592 | else if (keyvals[j] == GDK_KEY_Super_L0xffeb || |
593 | keyvals[j] == GDK_KEY_Super_R0xffec) |
594 | mask |= EGG_VIRTUAL_SUPER_MASK; |
595 | else if (keyvals[j] == GDK_KEY_Mode_switch0xff7e) |
596 | mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; |
597 | |
598 | ++j; |
599 | } |
600 | |
601 | /* Mod1Mask is 1 << 3 for example, i.e. the |
602 | * fourth modifier, i / keyspermod is the modifier |
603 | * index |
604 | */ |
605 | modmap->mapping[i/xmodmap->max_keypermod] |= mask; |
606 | |
607 | g_free (keyvals); |
608 | g_free (keys); |
609 | |
610 | ++i; |
611 | } |
612 | |
613 | /* Add in the not-really-virtual fixed entries */ |
614 | modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; |
615 | modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; |
616 | modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; |
617 | modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; |
618 | modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; |
619 | modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; |
620 | modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; |
621 | modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; |
622 | |
623 | XFreeModifiermap (xmodmap); |
624 | } |
625 | |
626 | const EggModmap* |
627 | egg_keymap_get_modmap (GdkKeymap *keymap) |
628 | { |
629 | EggModmap *modmap; |
630 | |
631 | /* This is all a hack, much simpler when we can just |
632 | * modify GDK directly. |
633 | */ |
634 | |
635 | modmap = g_object_get_data (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
636 | "egg-modmap"); |
637 | |
638 | if (modmap == NULL((void*)0)) |
639 | { |
640 | modmap = g_new0 (EggModmap, 1)(EggModmap *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s = sizeof (EggModmap); gpointer __p; if (__s == 1) __p = g_malloc0 (__n); else if (__builtin_constant_p (__n) && (__s == 0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p = g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p ; })); |
641 | |
642 | /* FIXME modify keymap change events with an event filter |
643 | * and force a reload if we get one |
644 | */ |
645 | |
646 | reload_modmap (keymap, modmap); |
647 | |
648 | g_object_set_data_full (G_OBJECT (keymap)((((GObject*) g_type_check_instance_cast ((GTypeInstance*) (( keymap)), (((GType) ((20) << (2)))))))), |
649 | "egg-modmap", |
650 | modmap, |
651 | g_free); |
652 | } |
653 | |
654 | g_assert (modmap != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if (modmap != ((void*)0)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message_expr (((gchar*) 0), "eggaccelerators.c", 654, ((const char*) (__func__ )), "modmap != NULL"); } while (0); |
655 | |
656 | return modmap; |
657 | } |